package org.yray.sip.packet;


import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.yray.sip.utils.ByteUtils;

@Data
@Slf4j
public  class BasePacket implements IPacket{


     public  static byte[] HEADER_REQ;
     public  static byte[] HEADER_RESP;
     static {
          HEADER_REQ=new byte[14];
          System.arraycopy(ByteUtils.uIntToByteWord(HEADER_FIRST),0,HEADER_REQ,0,2);
          System.arraycopy(ByteUtils.uIntToByteWord(HEADER_RESERVE),0,HEADER_REQ,2,2);
          System.arraycopy(ByteUtils.uLongTo8ByteWord(HEADER_SIGN),0,HEADER_REQ,4,8);
          System.arraycopy(ByteUtils.uIntToByteWord(HEADER_PACKET_TYPE),0,HEADER_REQ,12,2);

          HEADER_RESP=new byte[14];
          System.arraycopy(ByteUtils.uIntToByteWord(HEADER_FIRST),0,HEADER_RESP,0,2);
          System.arraycopy(ByteUtils.uIntToByteWord(HEADER_RESERVE_RESP),0,HEADER_RESP,2,2);
          System.arraycopy(ByteUtils.uLongTo8ByteWord(HEADER_SIGN),0,HEADER_RESP,4,8);
          System.arraycopy(ByteUtils.uIntToByteWord(HEADER_PACKET_TYPE),0,HEADER_RESP,12,2);
     }

     private int headerFirst;
     private int headerReserve;
     private long headerSign;
     private int headerPacketType;
     protected MsgType msgType;
     protected String key;
     protected int isResp=0;

     public static BasePacket basePacketOf(byte[] bs)
     {
          BasePacket basePacket=new BasePacket();
          basePacket.setHeaderFirst(ByteUtils.uBytes2Int(bs[0],bs[1]));
          basePacket.setHeaderReserve(ByteUtils.uBytes2Int(bs[2],bs[3]));
          byte[] bytesSign=new byte[8];
          System.arraycopy(bs,4,bytesSign,0,8);
          basePacket.setHeaderSign(ByteUtils.u8Bytes2Long(bytesSign));
          basePacket.setHeaderPacketType(ByteUtils.uBytes2Int(bs[12],bs[13]));
          basePacket.setMsgType(msgTypeOf(bs));
          return basePacket;
     }

     public static byte[] initHeader(int len,int msgType,byte[] header)
     {
          byte[] ret=new byte[len+16];
          System.arraycopy(header,0,ret,0,14);
          System.arraycopy(ByteUtils.uIntToByteWord(msgType),0,ret,14,2);
          return ret;
     }

     public static boolean instanceOf(byte[] bs)
     {

          return ByteUtils.uBytes2Int(bs[0],bs[1])==HEADER_FIRST;
     }
     public static MsgType msgTypeOf(byte[] bs)
     {

          int msgType=ByteUtils.uBytes2Int(bs[14],bs[15]);
          log.info("headerReqType={}",msgType);
          return MsgType.parseOf(msgType);
     }


     public byte[] toBytes()
     {
          String str= JSONObject.toJSONString(this);
          //log.info("msg={}",str);
          byte[] bsObj=str.getBytes();
          byte[] ret=initHeader(bsObj.length,this.getMsgType().getValue(),isResp==1?HEADER_RESP:HEADER_REQ);
          System.arraycopy(bsObj,0,ret,16,bsObj.length);
          return ret;
     }
}
